package com.jueling.culture.util;

import lombok.Data;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;

/**
 * @author linp
 * @date 2019/12/20
 */
@Data
public class CaptchaUtil {
    /**
     * 图片的宽度
     */
    private int width = 60;
    /**
     * 图片的高度
     */
    private int height = 32;
    /**
     * 验证码字符个数
     */
    private int codeCount = 4;
    /**
     * 验证码
     */
    private String code = null;

    private char[] codeSequence = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'M', 'N', 'P', 'Q', 'R',
            'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '2', '3', '4', '5', '6', '7', '8', '9'};
    /**
     * 生成随机数
     */
    private Random random = new Random();

    /**
     * 验证码图片Buffer
     */
    private BufferedImage buffImg;

    public CaptchaUtil(int width, int height, int codeCount) {
        this.width = width;
        this.height = height;
        this.codeCount = codeCount;
        this.createCode();
    }

    public CaptchaUtil() {
        this.createCode();
    }

    private void createCode() {
        int fontHeight = 0;
        // 字体的高度
        fontHeight = height - 13;
        int codeX = 0;
        // 每个字符的宽度
        codeX = width / (codeCount + 3);
        // 图像buffer
        buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = buffImg.createGraphics();
        // 将图像填充为白色
        graphics.setColor(Color.WHITE);
        graphics.fillRect(0, 0, width, height);
        //字体样式
        Font font = getFont(fontHeight);
        graphics.setFont(font);

        StringBuffer randomCode = new StringBuffer();
        // 随机产生验证码字符
        for (int i = 0; i < codeCount; i++) {
            String strRand = String.valueOf(codeSequence[random.nextInt(codeSequence.length)]);
            // 设置字体颜色
            graphics.setColor(getRandomColor());
            if(i==0){
                graphics.drawString(strRand, 3, getRandomNumber(3) + 25);
            }else{
                // 设置字体位置
                graphics.drawString(strRand, (i + 1) * (codeX+5)-10, getRandomNumber(3) + 22);
            }

            randomCode.append(strRand);
        }
        code = randomCode.toString();

    }

    /**
     * 获取随机颜色
     */
    private Color getRandomColor() {
        int r = getRandomNumber(255);
        int g = getRandomNumber(255);
        int b = getRandomNumber(255);
        return new Color(r, g, b);
    }

    /**
     * 获取随机数
     */
    private int getRandomNumber(int number) {
        return random.nextInt(number);
    }

    public void write(OutputStream sos) throws IOException {
        ImageIO.write(buffImg, "png", sos);
        sos.close();
    }

    public String img2String() throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(buffImg, "png", outputStream);
        byte[] bytes = outputStream.toByteArray();
        BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(bytes);
    }

    /**
     * 获取字体样式
     * @param fontHeight
     * @return
     */
    public Font getFont(int fontHeight) {
        return new Font("Arial", Font.PLAIN, fontHeight);
    }

}
